package com.dayatang.exam.domain;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

import com.dayatang.domain.ValueObject;

/**
 * 试题相关信息类�?从指定的题库中�?出指定题型�?指定数量的试题，同时指定每题的分数�?
 * 是从属于考试（Exam）类的�?对象�?
 * @author yang
 *
 */
@Embeddable
public class ExamQuestionInfo implements ValueObject{

	private static final long serialVersionUID = -286804135110273120L;

	/**
	 * 题库
	 */
	@ManyToOne
	@JoinColumn(name = "LIB_ID", nullable = false)
	private QuestionLib questionLib;

	/**
	 * 题型，单�?多�?/判断/填空/问题题之�?
	 */
	@Column(name = "QUESTION_TYPE", nullable = false)
	private String questionType;

	/**
	 * 题目数量
	 */
	@Column(name = "QUESTION_COUNT", nullable = true)
	private int questionCount;

	/**
	 * 分数
	 */
	@Column(name = "POINT", nullable = true)
	private int point;


	public ExamQuestionInfo() {
	}

	public ExamQuestionInfo(QuestionLib questionLib, String questionType, int questionCount, int point) {
		this.questionLib = questionLib;
		this.questionType = questionType;
		this.questionCount = questionCount;
		this.point = point;
	}

	public QuestionLib getQuestionLib() {
		return questionLib;
	}

	public void setQuestionLib(QuestionLib questionLib) {
		this.questionLib = questionLib;
	}

	public String getQuestionType() {
		return questionType;
	}

	public void setQuestionType(String questionType) {
		this.questionType = questionType;
	}

	public int getQuestionCount() {
		return questionCount;
	}

	public void setQuestionCount(int questionCount) {
		this.questionCount = questionCount;
	}

	public int getPoint() {
		return point;
	}

	public void setPoint(int point) {
		this.point = point;
	}

	private Class<? extends Question> getQuestionClass(String questionCategory) {
		if (questionType.equals(Question.TYPE_SINGLE_CHOICE)) {
			return SingleChoiceQuestion.class;
		}
		if (questionType.equals(Question.TYPE_MULTI_CHOICE)) {
			return MultiChoiceQuestion.class;
		}
		if (questionType.equals(Question.TYPE_JUDGEMENT)) {
			return JudgementQuestion.class;
		}
		if (questionType.equals(Question.TYPE_FILL_BLANK)) {
			return FillBlankQuestion.class;
		}
		if (questionType.equals(Question.TYPE_QUIZ)) {
			return QuizQuestion.class;
		}
		return null;
	}

	/**
	 * 生成试卷中的试题
	 * @return
	 * @throws QuestionInsufficientException
	 */
	public List<QuestionSolution> generateSolutions() throws QuestionInsufficientException {
		List<QuestionSolution> result = new ArrayList<QuestionSolution>();
		List<? extends Question> questions = questionLib.getRandomQuestions(getQuestionClass(questionType), questionCount);
		int position = 1;
		for (Question question : questions) {
			result.add(QuestionSolution.createQuestionSolution(question, point, position++));
		}
		return result;
	}

	public List<Question> generateQuestions() throws QuestionInsufficientException {
		List<Question> result = new ArrayList<Question>();
		return null;
	}

	@Override
	public boolean equals(final Object other) {
		if (!(other instanceof ExamQuestionInfo))
			return false;
		ExamQuestionInfo castOther = (ExamQuestionInfo) other;
		return new EqualsBuilder().append(questionLib, castOther.questionLib).append(questionType,
				castOther.questionType).append(questionCount, castOther.questionCount).append(point, castOther.point)
				.isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(questionLib).append(questionType).append(questionCount).append(point)
				.toHashCode();
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this).append("questionLib", questionLib).append("questionType", questionType)
				.append("questionCount", questionCount).append("point", point).toString();
	}


}
